#include <cmath>
#include "board.h"

bool sortList(Piece lhs, Piece rhs)
{
	// used to order the lost pieces
	return lhs.getRank() < rhs.getRank();
};

Board::Board(void)
: userColor(0), newGame(true), pieces(10, 10, Piece())
{
	// initializes the Board class and its objects
}

void Board::setPiece(const Posit position, const Piece newPiece)
{
	// sets the Piece at the given position
	pieces[position.getRow()][position.getCol()] = newPiece;
	return;
}

void Board::setUserColor(const int color)
{
	// saves the user's color
	userColor = color;
	return;
}

void Board::setNewGame(const bool startNew)
{
	// marks the newGame flag
	newGame = startNew;
	return;
}

bool Board::getNewGame(void) const
{
	// checks the newGame flag
	return newGame;
}

Piece Board::getPiece(const int row, const int col)
{
	// returns a piece at the given position
	if(row >= 0 && row <= 9 && col >= 0 && col <= 9) {
		return pieces[row][col];
	}
}

void Board::initializeBoard(void)
{
	// initializes the board
	// clear the lists that keep track of lost pieces
	userLost.clear();
	compLost.clear();
	int i, j;
	for(i = 0; i < 10; i++) {
		for(j = 0; j < 10; j++) {
			if(j%4 < 2 || i%6 < 4) {
				// fill the board with blank pieces
				pieces[i][j] = Piece();
			} else {
				// put the water pieces in
				pieces[i][j] = Piece(-2, -1, false);
			}
		}
	}
	return;
}

bool Board::movePiece(const int player, const Posit start, const Posit end)
{
	// move a piece. returns false if the move is illegal, true otherwise
	int i, dir;
	int j;
	Piece startPiece = pieces[start.getRow()][start.getCol()];
	Piece endPiece = pieces[end.getRow()][end.getCol()];
	if(startPiece.getOwner() != player) {
		// the piece must belong to the person whose turn it is
		return false;
	} else if(startPiece.getRank() > 9) {
		// bombs and flags cannot move
		return false;
	} else if(endPiece.getOwner() == player) {
		// cannot move to a square with a piece from the same team already on it
		return false;
	} else if(endPiece.getRank() == -2) {
		// cannot move to a water square
		return false;
	} else if(start.getRow() != end.getRow() && start.getCol() != end.getCol()) {
		// cannot move diagonally
		return false;
	} else if(start.getRow() == end.getRow() && start.getCol() == end.getCol()) {
		// cannot move to the same spot
		return false;
	} else if(startPiece.getRank() < 9) {
		// all pieces but scouts (and bombs and flags, which were already checked for)
		if((int)abs((float)(start.getRow() - end.getRow())) > 1) {
			// cannot move more than on space up or down
			return false;
		} else if((int)abs((float)(start.getCol() - end.getCol())) > 1) {
			// cannot move more than on space side to side
			return false;
		}
	} else if(start.getRow() == end.getRow()) {
		// the piece is a scout and is moving left or right
		// determine direction
		dir = (end.getCol() - start.getCol())/(int)abs((float)(end.getCol() - start.getCol()));
		for(i = start.getCol() + dir; i != end.getCol(); i += dir) {
			// check all the pieces between the scout and its destination
			if(pieces[start.getRow()][i].getRank() != -1) {
				// a piece is in the way
				return false;
			}
		}
	} else if(start.getCol() == end.getCol()) {
		// the piece is a scout and is moving up or down
		// determine direction
		dir = (end.getRow() - start.getRow())/(int)abs((float)(end.getRow() - start.getRow()));
		for(i = start.getRow() + dir; i != end.getRow(); i += dir) {
			// check all the pieces between the scout and its destination
			if(pieces[i][start.getCol()].getRank() != -1) {
				// a piece is in the way
				return false;
			}
		}
	}
	
	if(abs(start.getCol()-end.getCol()) > 1 || abs(start.getRow()-end.getRow()) > 1) {
		pieces[start.getRow()][start.getCol()].setKnown(true);
		startPiece.setKnown(true);
	}
	// if the function gets to this point, it is a legal move
	printAll();
	// show the previous move	
	if(start.getCol() == end.getCol()) {
		i = start.getRow();
		if(i > end.getRow()) {
			while(i != end.getRow()) {
				mvprintw(40 - i*4, 4 + start.getCol()*8 + 20, "\\/");
				i--;
			}
		} else {
			while(i != end.getRow()) {
				mvprintw(36 - i*4, 4 + start.getCol()*8 + 20, "/\\");
				i++;
			}
		}
	} else {
		i = start.getCol();
		if(i > end.getCol()) {
			while(i != end.getCol()) {
				mvprintw(38 - start.getRow()*4, i*8 + 20, "<-");
				i--;
			}
		} else {
			while(i != end.getCol()) {
				mvprintw(38 - start.getRow()*4, 8 + i*8 + 20, "->");
				i++;
			}
		}
	}
	// make the move
	if(endPiece.getOwner() == -1) {
		// if it is moving to a blank space, set the destination piece to be the piece that is moving
		pieces[end.getRow()][end.getCol()] = startPiece;
	} else {
		// the destination is occupied by an opposing piece, calculate the winner and move accordingly
		battle(player, start, end);
	}

	// replace the starting position with a blank space (no matter what)
	pieces[start.getRow()][start.getCol()] = Piece();

	// update the board, but show the previous move again
	printAll();
	if(start.getCol() == end.getCol()) {
		i = start.getRow();
		if(i > end.getRow()) {
			while(i != end.getRow()) {
				mvprintw(40 - i*4, 4 + start.getCol()*8 + 20, "\\/");
				i--;
			}
		} else {
			while(i != end.getRow()) {
				mvprintw(36 - i*4, 4 + start.getCol()*8 + 20, "/\\");
				i++;
			}
		}
	} else {
		i = start.getCol();
		if(i > end.getCol()) {
			while(i != end.getCol()) {
				mvprintw(38 - start.getRow()*4, i*8 + 20, "<-");
				i--;
			}
		} else {
			while(i != end.getCol()) {
				mvprintw(38 - start.getRow()*4, 8 + i*8 + 20, "->");
				i++;
			}
		}
	}
	return true;
}

void Board::swapPieces(const Posit start, const Posit end)
{
	// swaps two of your own pieces, used in the setup process
	Piece temp = pieces[start.getRow()][start.getCol()];
	pieces[start.getRow()][start.getCol()] = pieces[end.getRow()][end.getCol()];
	pieces[end.getRow()][end.getCol()] = temp;
	return;
}

bool Board::isDone(const int turn) {
	// checks to see if the game is over
	int i, j, k;
	// first check to see if either flag has been captured
	if(!userLost.empty()) {
		if(userLost.back().getRank() == 11) {
			// if the user's flag has been captured
			return true;
		}
	}
	if(!compLost.empty()) {
		if(compLost.back().getRank() == 11) {
			// if the computer's flag has been captured
			return true;
		}
	}
	
	// loop through every piece on the board. If it belongs to the correct player and it can move
	// the game is not over. If we fail to find a piece that can move, the game is over
	for (i=0; i<10; i++)
	{
		for (j=0; j<10; j++)
		{
			// if it belongs to the correct player AND it is not a flag AND it is not a bomb
			if (pieces[i][j].getOwner() == turn && pieces[i][j].getRank()!=10 && pieces[i][j].getRank()!=11)
			{
				// if there is an open space or an enemy piece nearby it can move, the game is not over
				if (i<9){
					if(pieces[i+1][j].getOwner() != turn && pieces[i+1][j].getRank() != -2) {
						return false;
					}
				}
				if (j<9)
				{
					if(pieces[i][j+1].getOwner() != turn && pieces[i][j+1].getRank() != -2) {
						return false;
					}
				}
				if (i>0){
					if(pieces[i-1][j].getOwner() != turn && pieces[i-1][j].getRank() != -2) {
						return false;
					}
				}
				if (j>0){
					if(pieces[i][j-1].getOwner() != turn && pieces[i][j-1].getRank() != -2) {
						return false;
					}
				}
			}
		}
	}

	// if neither flag is captured, but the current player can't move, the game is over
	return true;
}

void Board::printAll(void)
{
	// print all parts of the graphics
	printMenu();
	printBoard();
	printBase();
	refresh();
	return;
}

void Board::printMenu(void)
{
	// print the menu buttons
	attron(COLOR_PAIR(8));
	mvprintw(1,4,"  New Game  ");
	mvprintw(3,4," View Rules ");
	mvprintw(5,4,"    Quit    ");
	mvprintw(7,4,"  Captured  ");
	mvprintw(8,4,"   Pieces   ");
	attroff(COLOR_PAIR(8));
	return;
}

void Board::printBoard(void)
{
	// print the game board
	int i, j;
	for(i = 0; i < 41; i++) {
		for(j = 0; j < 82; j++) {
			if(i%4 == 0 || j%8 == 0 || (j-1)%8 == 0) {
				// print black lines between the squares
				attron(COLOR_PAIR(7));
				mvprintw(i, j + 20, " ");
				attroff(COLOR_PAIR(7));
			} else {
				// print the piece at that position
				printPiece(9-i/4,j/8,0);
			}
		}
	}
	return;
}

void Board::printPiece(const int row, const int col, const int selected)
{
	// prints the piece on the board at the given position
	Piece thePiece = pieces[row][col];
	string pieceRep;
	int i, j, theRank;
	j = 0;
	for(i = 39 - row*4; i > 36 - row*4; i--) {
		// prints all 3 ncurses rows that the piece covers
		if(thePiece.getOwner() == 0) {
			// selects a color based on the users color and whether or not the piece is selected
			attron(COLOR_PAIR(userColor*2 + 1 + (selected+1)/2));
			if(j == 1) {
				// j is 1 for the middle ncurses row, and the rank is printed
				mvprintw(i, 2 + col*8 + 20, "  %c   ", thePiece.getShortDescr());
			} else {
				// the top and bottom ncurses rows are blank, just the color of the piece
				mvprintw(i, 2 + col*8 + 20, "      ");
			}
			attroff(COLOR_PAIR(userColor*2 + 1 + (selected+1)/2));
		} else if(thePiece.getOwner() == 1) {
			// selects a color based on the users color and whether or not the piece is selected
			attron(COLOR_PAIR((userColor - 1)*(-2) + 1 + (selected+1)/2));
			if(j == 1) {
				// j is 1 for the middle ncurses row, and a ? is printed
				mvprintw(i, 2 + col*8 + 20, "  ?   ");
			} else {
				// the top and bottom ncurses rows are blank, just the color of the piece
				mvprintw(i, 2 + col*8 + 20, "      ");
			}
			attroff(COLOR_PAIR((userColor - 1)*(-2) + 1 + (selected+1)/2));
		} else if(thePiece.getRank() == -1) {
			// the piece is an open space, print a green square
			attron(COLOR_PAIR(5));
			mvprintw(i, 2 + col*8 + 20, "      ");
			attroff(COLOR_PAIR(5));
		} else if(thePiece.getRank() == -2) {
			// the piece is water, print a water square
			attron(COLOR_PAIR(6));
			if(j == 1) {
				mvprintw(i, 2 + col*8 + 20, " ~ ~ ~");
			} else {
				mvprintw(i, 2 + col*8 + 20, "~ ~ ~ ");
			}
			attroff(COLOR_PAIR(6));
		}
		j++;
	}

	// print arrows showing possible moves
	// when selected is 2, the piece is selected, but we are in setup and swapping pieces,
	// so we do not draw the arrows
	if(selected == 1 && pieces[row][col].getRank() < 10) {
		// if the piece is selected, and it is a movable piece
		if(row > 0) {
			// if the piece is not on the bottom board row
			for(i = row - 1; i > -1; i--) {
				if(pieces[i][col].getOwner() == -1 && pieces[i][col].getRank() != -2 && (i==(row - 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move down, print \/ below it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(40 - (i + 1)*4, 4 + col*8 + 20, "\\/");
					attron(COLOR_PAIR(7));
				} else if(pieces[i][col].getOwner() == 1 && (i==(row - 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move down, print \/ below it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(40 - (i + 1)*4, 4 + col*8 + 20, "\\/");
					attron(COLOR_PAIR(7));
					i = -1;
				} else {
					i = -1;
				}
			}
		}
		if(row < 9) {
			// if the piece is not on the top board row
			for(i = row + 1; i < 10; i++) {
				if(pieces[i][col].getOwner() == -1 && pieces[i][col].getRank() != -2 && (i==(row + 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move up, print /\ above it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(36 - (i - 1)*4, 4 + col*8 + 20, "/\\");
					attron(COLOR_PAIR(7));
				} else if(pieces[i][col].getOwner() == 1 && (i==(row + 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move up, print /\ above it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(36 - (i - 1)*4, 4 + col*8 + 20, "/\\");
					attron(COLOR_PAIR(7));
					i = 10;
				} else {
					i = 10;
				}
			}
		}
		if(col > 0) {
			// if the piece is not on the far left board column
			for(i = col - 1; i > -1; i--) {
				if(pieces[row][i].getOwner() == -1 && pieces[row][i].getRank() != -2 && (i==(col - 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move left, print <- next to it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(38 - row*4, (i + 1)*8 + 20, "<-");
					attron(COLOR_PAIR(7));
				} else if(pieces[row][i].getOwner() == 1 && (i==(col - 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move left, print <- next to it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(38 - row*4, (i + 1)*8 + 20, "<-");
					attron(COLOR_PAIR(7));
					i = -1;
				} else {
					i = -1;
				}
			}
		}
		if(col < 9) {
			// if the piece is not on the far right board column
			for(i = col + 1; i < 10; i++) {
				if(pieces[row][i].getOwner() == -1 && pieces[row][i].getRank() != -2 && (i==(col + 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move right, print -> next to it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(38 - row*4, 8 + (i - 1)*8 + 20, "->");
					attron(COLOR_PAIR(7));
				} else if(pieces[row][i].getOwner() == 1 && (i==(col + 1) || pieces[row][col].getRank() == 9)) {
					// if the piece can move right, print -> next to it to show the possible move
					attron(COLOR_PAIR(7));
					mvprintw(38 - row*4, 8 + (i - 1)*8 + 20, "->");
					attron(COLOR_PAIR(7));
					i = 10;
				} else {
					i = 10;
				}
			}
		}
	}

	return;
}

void Board::printBase(void)
{
	// print the bottom part, with the word stratego and information about the pieces,
	// with the letter/number abbreviation, the name, and how many of that piece there are
	mvprintw(41,0 + 20,"                                                                                  ");
	mvprintw(42,0 + 20,"  F - Flag (1)     #### ##### ###  ##### ##### #### #### ####  6 - Lieutenant (4) ");
	mvprintw(43,0 + 20,"  1 - Marshal (1)  #      #   #  # #   #   #   #    #    #  #  7 - Sergeant (4)   ");
	mvprintw(44,0 + 20,"  2 - General (1)  ####   #   ###  #####   #   ###  # ## #  #  8 - Miner (5)      ");
	mvprintw(45,0 + 20,"  3 - Colonel (2)     #   #   # #  #   #   #   #    #  # #  #  9 - Scout (8)      ");
	mvprintw(46,0 + 20,"  4 - Major (3)    ####   #   #  # #   #   #   #### #### ####  S - Spy (1)        ");
	mvprintw(47,0 + 20,"  5 - Captain (4)                                              B - Bomb (6)       ");

	return;
}

void Board::battle(const int player, const Posit start, const Posit end)
{
	// calculates the winner when there is an attack
	int inputCh, top, bottom;
	bool done = false;
	MEVENT event;
	Piece startPiece = pieces[start.getRow()][start.getCol()];
	Piece endPiece = pieces[end.getRow()][end.getCol()];
	// the attacking piece is shown on top, the colors need to be set
	if(player == userColor) {
		// if the player is red and attacking, or blue and being attacked, the top piece is red
		top = 1;
		bottom = 3;
	} else {
		// otherwise, the top piece is blue
		top = 3;
		bottom = 1;
	}

	while(!done) {
		// loops through until the user chooses to continue

		// print the pieces and a continue button
		attron(COLOR_PAIR(top));
		mvprintw(10, 7, "      ");
		mvprintw(11, 7, "  %c   ", startPiece.getShortDescr());
		mvprintw(12, 7, "      ");
		attroff(COLOR_PAIR(top));

		attron(COLOR_PAIR(bottom));
		mvprintw(14, 7, "      ");
		mvprintw(15, 7, "  %c   ", endPiece.getShortDescr());
		mvprintw(16, 7, "      ");
		attroff(COLOR_PAIR(bottom));

		attron(COLOR_PAIR(8));
		mvprintw(18, 4, "  Continue  ");
		attroff(COLOR_PAIR(8));

		// get the user input
		inputCh = getch();
		if(inputCh == KEY_MOUSE) {
				if(getmouse(&event) == OK) {		  
				if(event.bstate & BUTTON1_CLICKED) {
					if(newGame = checkMenu(event.x, event.y)) {
						// check to see if the user pressed any of the regular menu keys
						if(newGame == 1) {
							// if the user pressed the New Game key, set the flag and exit this loop
							setNewGame(true);
							done = true;
						}
					} else if (event.x > 3 && event.x < 17 && event.y == 18) {
						// if the user pressed the Continue button, continue
						done = true;
					}	
				}
			}
		}
	}

	// clear the area under the menu
	mvprintw(10, 7, "      ");
	mvprintw(11, 7, "      ");
	mvprintw(12, 7, "      ");
	mvprintw(14, 7, "      ");
	mvprintw(15, 7, "      ");
	mvprintw(16, 7, "      ");
	mvprintw(18, 4, "            ");
	refresh();

	// calculate the winner
	if(startPiece.getRank() == endPiece.getRank()) {
		// if they are equal, they both lose
		// set the destination point as empty, the starting point will be cleared back in the move function
		pieces[end.getRow()][end.getCol()] = Piece();
		// put the pieces in the correct lost lists, depending on who attacked, and sort the lists
		if(player == 0) {
			userLost.push_back(startPiece);
			userLost.sort(sortList);
			compLost.push_back(endPiece);
			compLost.sort(sortList);
		} else {
			userLost.push_back(endPiece);
			userLost.sort(sortList);
			compLost.push_back(startPiece);
			compLost.sort(sortList);
		}
	} else if(endPiece.getRank() == 0) {
		// if the spy got attacked, he loses
		// move the winning piece
		pieces[end.getRow()][end.getCol()] = startPiece;
		// put the spy in the correct lost list, depending on who attacked, and sort the list
		if(player == 0) {
			compLost.push_back(endPiece);
			compLost.sort(sortList);
			pieces[end.getRow()][end.getCol()].setKnown(true);
		} else {
			userLost.push_back(endPiece);
			userLost.sort(sortList);
		}
	} else if(startPiece.getRank() == 0 && endPiece.getRank()%10 != 1) {
		// if a spy attacks anyone other than a marshal or flag, he loses
		// put the spy in the correct lost list, depending on who attacked, and sort the list
		if(player == 0) {
			userLost.push_back(startPiece);
			userLost.sort(sortList);
		} else {
			compLost.push_back(startPiece);
			compLost.sort(sortList);
			pieces[end.getRow()][end.getCol()].setKnown(true);
		}
	} else if(startPiece.getRank() != 8 && endPiece.getRank() == 10) {
		// if a bomb got attacked by anyone other than a miner, it wins
		// put the attacking piece in the correct lost list, depending on who attacked, and sort the list
		if(player == 0) {
			userLost.push_back(startPiece);
			userLost.sort(sortList);
		} else {
			compLost.push_back(startPiece);
			compLost.sort(sortList);
			pieces[end.getRow()][end.getCol()].setKnown(true);
		}
	} else if(startPiece.getRank() > endPiece.getRank()) {
		// if the attacking piece is higher, it loses
		// the only exception is if the marshal is attacking the spy
		// but we already checked whether the piece being attacked was the spy
		// put the losing piece in the correct lost list, depending on who attacked, and sort the list
		if(player == 0) {
			userLost.push_back(startPiece);
			userLost.sort(sortList);
		} else {
			compLost.push_back(startPiece);
			compLost.sort(sortList);
			pieces[end.getRow()][end.getCol()].setKnown(true);
		}
	} else if(startPiece.getRank() < endPiece.getRank()) {
		// if the attacking piece is lower, it wins
		// the only exception is if anyone other than miner attacks a bomb,
		// but we already checked whether the piece being attacked was a bomb,
		// or if a spy is attacking anyone other than a marshal or a flag,
		// but we already checked for that too
		// move the winning piece into the destination square
		pieces[end.getRow()][end.getCol()] = startPiece;
		// put the losing piece in the correct lost list, depending on who attacked, and sort the list
		if(player == 0) {
			compLost.push_back(endPiece);
			compLost.sort(sortList);
			pieces[end.getRow()][end.getCol()].setKnown(true);
		} else {
			userLost.push_back(endPiece);
			userLost.sort(sortList);
		}
	}

	return;
}

int Board::checkMenu(const int x, const int y)
{
	// checks whether a menu button was pressed and returns the appropriate value
	int inputCh;
	bool done = false;
	MEVENT event;
	if(x > 3 && x < 17 && y == 1) {
		// the New Game button was pressed
		return 1;
	} else if(x > 3 && x < 17 && y == 3) {
		// the View Rules button was pressed
		// clear the screen
		clear();
		// print a button to return to the game
		attron(COLOR_PAIR(8));
		mvprintw(1, 2, " Return to Game ");
		attroff(COLOR_PAIR(8));
		// print the rules
		printRules();
		refresh();

		// loop until the Return to Game button is pressed
		while(!done) {
			inputCh = getch();
			if(inputCh == KEY_MOUSE) {
				if(getmouse(&event) == OK) {		  
					if(event.bstate & BUTTON1_CLICKED) {
						if(event.x > 1 && event.x < 18 && event.y == 1) {
							// if the button was pressed, break the loop
							done = true;
						}
					}
				}
			}
		}
		// clear the screen
		clear();
		// print all of the regular stuff
		printAll();
		refresh();
		return 2;
	} else if(x > 3 && x < 17 && y == 5) {
		// the Quit button was pressed
		// end ncurses and exit
		endwin();
		exit(0);
	} else if(x > 3 && x < 17 && (y == 7 || y == 8)) {
		// the Captures Pieces button was pressed
		// clear the screen
		clear();
		// print a button to return to the game
		attron(COLOR_PAIR(8));
		mvprintw(1, 2, " Return to Game ");
		attroff(COLOR_PAIR(8));
		// display the captured pieces
		printCapt();
		refresh();

		// loop until the Return to Game button is pressed
		while(!done) {
			inputCh = getch();
			if(inputCh == KEY_MOUSE) {
				if(getmouse(&event) == OK) {		  
					if(event.bstate & BUTTON1_CLICKED) {
						if(event.x > 1 && event.x < 18 && event.y == 1) {
							// if the button was pressed, break the loop
							done = true;
						}
					}
				}
			}
		}
		// clear the screen
		clear();
		// print all of the regular stuff
		printAll();
		refresh();
		return 3;
	}
	return 0;
}

void Board::printRules(void)
{
	// prints all the rules
	mvprintw( 3,6, "The object of the game is to capture the opponent's flag.");
	mvprintw( 4,6, "To start the game, place your pieces on your half of the board. Choose a location on the board");
	mvprintw( 5,6, "  to place the piece in that location. You also have the option to randomly place all your");
	mvprintw( 6,6, "  pieces. Once your pieces have been placed, you can move them around until you are done.");
	mvprintw( 7,6, "Each player gets an army of 40 pieces, in order of rank from high to low, consisting of:");
	mvprintw( 8,6, "  1 Marshal, 1 General, 2 Colonels, 3 Majors, 4 Captains, 4 Lieutenants, 4 Sergeants, 5 Miners,");
	mvprintw( 9,6, "  8 Scouts, and 1 Spy. These are all movable pieces. There are also 6 Bombs and 1 Flag, which");
	mvprintw(10,6, "  are not moveable. The pieces display a number or letter to designate the rank.");
	mvprintw(11,6, "Rules for Movement");
	mvprintw(12,6, "  1. Turns alternate, first Red then Blue.");
	mvprintw(13,6, "  2. A piece moves from square to square, one square at a time. (Exception: Scout - see rule 8).");
	mvprintw(14,6, "     A piece may be moved forward, backward, or sideward but not diagonally.");
	mvprintw(15,6, "  3. There are two lakes in the center of the board. Pieces must move around lakes.");
	mvprintw(16,6, "  4. Two pieces may not occupy the same square at the same time.");
	mvprintw(17,6, "  6. Only one piece may be moved in each turn.");
	mvprintw(18,6, "  7. The Flag and the Bomb pieces cannot be moved. Once these pieces are placed at the start of");
	mvprintw(19,6, "     the game, they must remain in that square.");
	mvprintw(20,6, "  8. The Scout may move any number of open squares forward, backward, or sideward in a straight");
	mvprintw(21,6, "     line if the player desires. The scout cannot move through spaces that are occupied.");
	mvprintw(22,6, "Rules for Strike or Attack");
	mvprintw(23,6, "  1. When a red and a blue piece occupy adjoining squares either back to back, side to side, or");
	mvprintw(24,6, "     face to face, they are in a position to attack or strike. No diagonal strikes can be made.");
	mvprintw(25,6, "  2. A player may move in his turn or strike in his turn. He cannot do both.  (Exception: Scout");
	mvprintw(26,6, "     - see rule 10). The strike ends the turn.");
	mvprintw(27,6, "  3. It is not required to strike when two opposing pieces are in position.");
	mvprintw(28,6, "  4. The piece with the lower rank is lost and removed from the board. If the striking piece is");
	mvprintw(29,6, "     the remaining and winning piece, it moves into the space formerly occupied by the defending");
	mvprintw(30,6, "     piece. If the remaining and winning piece is the defending piece, it stays on the square it");
	mvprintw(31,6, "     was in when it was struck");
	mvprintw(32,6, "  5. When equal ranks are struck, then both pieces are lost and removed from the board.");
	mvprintw(33,6, "  6. A Marshal removes a General, a General removes a Colonel, and a Colonel removes a Major,");
	mvprintw(34,6, "     and so on down to the Spy, which is the lowest ranking piece.");
	mvprintw(35,6, "  7. The Spy, however, has the special privilege of being able to remove only the Marshal");
	mvprintw(36,6, "     provided he strikes first. That is, if the Spy strikes the Marshal in his turn, the Marshal");
	mvprintw(37,6, "     is removed. However, if the Marshal strikes first, the Spy is removed. All other pieces");
	mvprintw(38,6, "     remove the Spy regardless of who strikes first.");
	mvprintw(39,6, "  8. When any piece (except a Miner) strikes a Bomb that piece is lost and is removed from the");
	mvprintw(40,6, "     board. The bomb remains on the board. When a Miner strikes a Bomb, the Bomb is lost and the");
	mvprintw(41,6, "     miner moves into the unoccupied square.");
	mvprintw(42,6, "  9. A Bomb cannot strike, but rather must wait until a moveable piece strikes it.");
	mvprintw(43,6, "  9. A Scout can move and strike in the same turn, provided the move and strike are in the same");
	mvprintw(44,6, "     direction.");
	mvprintw(45,6, "To End the Game");
	mvprintw(46,6, "  Whenever a player strikes his opponent's Flag, the game ends and he is the winner. If a player");
	mvprintw(47,6, "  cannot move or strike in his turn, he must give up and declare his opponent the winner.");
}

void Board::printCapt(void)
{
	// displays the captured pieces
	list<Piece>::iterator it;
	int nextRow = 3, nextCol = 6;
	if(userLost.empty()) {
		// if the user has not lost any pieces
		mvprintw(nextRow, nextCol, "You have not lost any pieces.");
	} else {
		// the user has lost pieces; show them
		mvprintw(nextRow, nextCol, "Pieces you have lost:");
		nextRow += 2;
		// set the color based on the color the user should be
		attron(COLOR_PAIR(userColor*2 + 1));
		for(it = userLost.begin(); it != userLost.end(); it++) {
			// loop through all the pieces
			if(nextCol > 78) {
				// if there are ten pieces in the row, start another row
				nextRow += 4;
				nextCol = 6;
			}
			// print the piece
			mvprintw(nextRow, nextCol, "      ");
			mvprintw(nextRow+1, nextCol, "  %c   ", it->getShortDescr());
			mvprintw(nextRow+2, nextCol, "      ");
			// move over to print the next piece
			nextCol += 8;
		}
		attroff(COLOR_PAIR(userColor*2 + 1));
	}
	// move down to print the computer's lost pieces
	nextRow += 6;
	nextCol = 6;
	if(compLost.empty()) {
		// if the computer has not lost any pieces
		mvprintw(nextRow, nextCol, "Your opponent has not lost any pieces.");
	} else {
		// the computer has lost pieces; show them
		mvprintw(nextRow, nextCol, "Pieces your opponent has lost:");
		nextRow += 2;
		// set the color based on the color the user should be
		attron(COLOR_PAIR((userColor - 1)*(-2) + 1));
		for(it = compLost.begin(); it != compLost.end(); it++) {
			// loop through all the pieces
			if(nextCol > 78) {
				// if there are ten pieces in the row, start another row
				nextRow += 4;
				nextCol = 6;
			}
			// print the piece
			mvprintw(nextRow, nextCol, "      ");
			mvprintw(nextRow+1, nextCol, "  %c   ", it->getShortDescr());
			mvprintw(nextRow+2, nextCol, "      ");
			// move over to print the next piece
			nextCol += 8;
		}
		attroff(COLOR_PAIR((userColor - 1)*(-2) + 1));
	}
}

